﻿using System;
using System.IO;
using System.Net;
using System.Text;
using System.Net.Cache;
using Eff.Commons;

namespace Eff.Net
{
    /// <summary>
    /// HttpHelper 的摘要说明
    /// </summary>
    public class HttpHelper
    {
        #region Get方式请求一个Url

        /// <summary>
        /// Get方式请求一个Url
        /// </summary>
        /// <param name="urlStr"></param>
        /// <param name="timeOut"></param>
        /// <returns>返回收到包的字节流</returns>
        public static byte[] Get(string urlStr, int timeOut = 2000)
        {
            try
            {
                var myRequest = (HttpWebRequest)WebRequest.Create(urlStr);
                myRequest.Method = "GET";
                myRequest.ContentType = "text/xml";
                myRequest.Accept = "*/*";
                myRequest.Timeout = timeOut;
                myRequest.UserAgent = "Mozilla-Firefox-Spider(Effective)";
                myRequest.ServicePoint.Expect100Continue = false;

                var noCachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore);
                myRequest.CachePolicy = noCachePolicy;

                var byteArr = new byte[256];
                Stream streamRequest = myRequest.GetResponse().GetResponseStream();
                var bytes = new Bytes();
                if (streamRequest != null)
                {
                    int count = streamRequest.Read(byteArr, 0, 256);
                    while (count > 0)
                    {
                        bytes.WriteByteArr(Bytes.ByteSub(byteArr, 0, count));
                        count = streamRequest.Read(byteArr, 0, 256);
                    }
                    streamRequest.Close();
                }

                return bytes.GetByte;
            }
            catch (Exception exception)
            {
                LogHelper.Log.Debug("Effective.Net.HttpHelper.Get.urlStr=" + urlStr + ",exception=" + exception +
                                     exception.Source + exception.StackTrace);
            }
            return null;
        }


        /// <summary>
        /// Get一个url,带返回信息
        /// </summary>
        /// <param name="urlStr">URL地址</param>
        /// <param name="timeOut">超时时间</param>
        /// <param name="encoding">字符编码</param>
        /// <returns></returns>
        public static string RequestGetWithReturn(string urlStr, int timeOut = 2000, Encoding encoding = null)
        {
            try
            {
                if (encoding == null) encoding = Encoding.Default;

                var myRequest = (HttpWebRequest)WebRequest.Create(urlStr);
                myRequest.Method = "GET";
                myRequest.ContentType = "text/xml";
                myRequest.Accept = "*/*";
                myRequest.Timeout = timeOut;
                myRequest.UserAgent = "Mozilla-Firefox-Spider(Effective)";
                myRequest.ServicePoint.Expect100Continue = false;

                var noCachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore);
                myRequest.CachePolicy = noCachePolicy;

                Stream streamRequest = myRequest.GetResponse().GetResponseStream();
                if (streamRequest != null)
                {
                    var streamReader = new StreamReader(streamRequest, encoding);
                    string strContent = streamReader.ReadToEnd();
                    streamReader.Close();
                    streamRequest.Close();
                    return strContent;
                }
            }
            catch (Exception exception)
            {
                LogHelper.Log.Debug("Effective.Net.HttpHelper.RequestGetWithReturn.urlStr=" + urlStr + ",exception=" + exception +
                                     exception.Source + exception.StackTrace);
            }
            return "";
        }

        #endregion

        #region Post一个数据，返回源代码


        /// <summary>
        /// Post一个数据，返回源代码
        /// </summary>
        /// <param name="urlStr">UrlStr</param>
        /// <param name="data">data</param>
        /// <param name="timeOut">timeOur</param>
        /// <param name="encoding">encoding</param>
        /// <returns></returns>
        public static string PostWithReturn(string urlStr, string data, int timeOut = 2000, Encoding encoding = null)
        {
            string strContent = "";
            try
            {
                if (encoding == null) encoding = Encoding.Default;
                var myRequest = (HttpWebRequest)WebRequest.Create(urlStr);
                myRequest.Method = "POST";
                myRequest.ContentType = "text/xml";
                myRequest.Accept = "*/*";
                myRequest.Timeout = timeOut;
                myRequest.UserAgent = "Mozilla-Firefox-Spider(Effective)";
                Stream streamSend = myRequest.GetRequestStream();
                var myStreamWriter = new StreamWriter(streamSend, encoding);
                myStreamWriter.Write(data);
                myStreamWriter.Close();
                streamSend.Close();

                Stream streamRequest = myRequest.GetResponse().GetResponseStream();
                if (streamRequest != null)
                {
                    var myStreamReader = new StreamReader(streamRequest, encoding);
                    strContent = myStreamReader.ReadToEnd();
                    myStreamReader.Close();
                    streamRequest.Close();
                }

                return strContent;
            }
            catch (Exception exception)
            {
                LogHelper.Log.Debug("Effective.Net.HttpHelper.PostWithReturn.urlStr=" + urlStr + ",exception=" + exception +
                                     exception.Source + exception.StackTrace);
            }
            return strContent;
        }
        #endregion

        #region 给Url发送一个流数据Demo使用的测试数据流

        public static byte[] Post(string urlStr, string data, int timeOut = 2000, string encoding = "utf-8")
        {
            var byteData = Encoding.GetEncoding(encoding).GetBytes(data);
            return Post(urlStr, byteData, timeOut);
        }

        /// <summary>
        /// 给Url发送一个流数据
        /// </summary>
        /// <param name="data">Data</param>
        /// <param name="urlStr">Url</param>
        /// <param name="timeOut">超时时间</param>
        /// <returns>返回收到包的字节流</returns>
        public static byte[] Post(string urlStr, byte[] data, int timeOut = 2000)
        {
            try
            {
                Stream streamSend = null;
                var myRequest = (HttpWebRequest)WebRequest.Create(urlStr);
                myRequest.Method = "POST";
//                myRequest.ContentType = "text/xml";
                myRequest.ContentType = "application/x-www-form-urlencoded";
                myRequest.Accept = "*/*";
                myRequest.Timeout = timeOut;
                myRequest.UserAgent = "Mozilla-Firefox-Spider(Effective)";
                myRequest.ContentLength = data.Length;
                //这个在Post的时候，一定要加上，如果服务器返回错误，他还会继续再去请求
                //不会使用之前的错误数据，做返回数据
                myRequest.ServicePoint.Expect100Continue = false;

                var noCachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore);
                myRequest.CachePolicy = noCachePolicy;

                try
                {
                    streamSend = myRequest.GetRequestStream();
                    streamSend.Write(data, 0, data.Length);
                    streamSend.Close();
                }
                catch (WebException wex)
                {
                    LogHelper.Log.Debug("Effective.Net.HttpHelper.WebException=" + wex + ",wex.Status=" +
                                         wex.Status);
                    if (streamSend != null)
                        streamSend.Close();
                    return null;
                }
                catch (Exception ex)
                {
                    LogHelper.Log.Debug("Effective.Net.HttpHelper.GetRequestStream=" + ex);
                    if (streamSend != null)
                        streamSend.Close();
                    return null;
                }

                var byteArr = new byte[256];
                Stream streamRequest = null;
                try
                {
                    streamRequest = myRequest.GetResponse().GetResponseStream();
                }
                catch (Exception httpex)
                {
                    LogHelper.Log.Debug("Effective.Net.HttpHelper.SendRequest=" + httpex);
                    if (streamRequest != null)
                        streamRequest.Close();
                    return null;
                }
                var bytes = new Bytes();
                if (streamRequest != null)
                {
                    int count = streamRequest.Read(byteArr, 0, 256);
                    while (count > 0)
                    {
                        bytes.WriteByteArr(Bytes.ByteSub(byteArr, 0, count));
                        count = streamRequest.Read(byteArr, 0, 256);
                    }
                    streamRequest.Close();
                }

                return bytes.GetByte;
            }
            catch (Exception eee)
            {
                LogHelper.Log.Debug("Effective.Net.HttpHelper.Post.urlStr=" + urlStr + eee.Source + eee.StackTrace);
            }
            return null;
        }
        #endregion

        #region 下载文件,支持301,302跳转下载
        /// <summary>
        /// 下载文件,支持301,302跳转下载
        /// </summary>
        /// <param name="diskPaht">文件物理地址</param>
        /// <param name="strName">文件名称,如果文件名为null或empty,将取Url地址的文件名</param>
        /// <param name="sourceUrl">下载的Url地址</param>
        public static void SaveFile(string diskPaht, string strName, string sourceUrl)
        {
            if (string.IsNullOrEmpty(strName))
                strName = sourceUrl.Remove(0, sourceUrl.LastIndexOf("/") + 1);
            //string path = DateTime.Now.Year + @"\" + DateTime.Now.Month + @"\" + DateTime.Now.Day + @"\";
            //创建一个新文件夹
            if (!Directory.Exists(diskPaht)) Directory.CreateDirectory(diskPaht);

            string filePath = strName;
            FileStream fs = null;
            //打开网络连接 
            try
            {
                var request = (HttpWebRequest)WebRequest.Create(sourceUrl);
                var response = (HttpWebResponse)request.GetResponse();
                //long length = response.ContentLength;
                //这里为了支持:301,302跳转
                if ((response.StatusCode == HttpStatusCode.Moved
                     || response.StatusCode == HttpStatusCode.Redirect)
                    && request.Address.ToString() != sourceUrl)
                {
                    SaveFile(diskPaht, strName, request.Address.ToString());
                }

                string contentType = response.Headers["Content-Type"];
                if (contentType.IndexOf(';') > 0)
                    contentType = contentType.Substring(0, contentType.IndexOf(';'));
                string strPostfix = "";

                //常用文件下载方法
                switch (contentType)
                {
                    case "video/flv":
                        strPostfix = "flv";
                        break;
                    case "video/x-flv":
                        strPostfix = "flv";
                        break;
                    case "application/zip":
                        strPostfix = "zip";
                        break;
                    case "audio/mpeg":
                        strPostfix = "mp3";
                        break;
                    case "application/xml":
                        strPostfix = "xml";
                        break;
                    case "image/png":
                        strPostfix = "png";
                        break;
                    case "text/css":
                        strPostfix = "css";
                        break;
                    case "image/jpeg":
                        strPostfix = "jpg";
                        break;
                    case "image/gif":
                        strPostfix = "gif";
                        break;
                    case "text/plain":
                        strPostfix = "txt";
                        break;
                    case "text/html":
                        strPostfix = "html";
                        break;
                    case "image/x-icon":
                        strPostfix = "ico";
                        break;
                    case "application/x-javascript":
                        strPostfix = "js";
                        break;
                    case "application/pdf":
                        strPostfix = "pdf";
                        break;
                }

                //如果有类型,使用这个Type类型
                if (strPostfix.Length > 0)
                    filePath = filePath.Remove(filePath.LastIndexOf('.') + 1) + strPostfix;

                //创建一个新文件
                if (File.Exists(diskPaht + filePath))
                    File.Delete(diskPaht + filePath);
                fs = new FileStream(diskPaht + filePath, FileMode.Create);

                //向服务器请求，获得服务器回应数据流 
                Stream ns = request.GetResponse().GetResponseStream();

                var nbytes = new byte[512];
                if (ns != null)
                {
                    int nReadSize = ns.Read(nbytes, 0, nbytes.Length);
                    while (nReadSize > 0)
                    {
                        fs.Write(nbytes, 0, nReadSize);
                        nReadSize = ns.Read(nbytes, 0, nbytes.Length);
                    }
                    ns.Close();
                }
                fs.Close();

            }
            catch (Exception)
            {
                if (fs != null)
                    fs.Close();
            }
        }

        #endregion

    }
}

